<section data-type="chapter" id="_chapter_3_oscillation">
  <h1>Chapter 3. Oscillation</h1>

  <blockquote data-type="epigraph">
    <p>“Trigonometry is a sine of the times.”</p>

    <p data-type="attribution">— Anonymous</p>
  </blockquote>

  <p>
    In Chapters 1 and 2, we carefully worked out an object-oriented structure to
    make something move on the screen, using the concept of a vector to
    represent position, velocity, and acceleration driven by forces in the
    environment. We could move straight from here into topics such as particle
    systems, steering forces, group behaviors, etc. If we did that, however,
    we’d skip an important area of mathematics that we’re going to need:
    <strong><em>trigonometry</em></strong
    >, or the mathematics of triangles, specifically right triangles.
  </p>

  <p>
    Trigonometry is going to give us a lot of tools. We’ll get to think about
    angles and angular velocity and acceleration. Trig will teach us about the
    sine and cosine functions, which when used properly can yield a nice
    ease-in, ease-out wave pattern. It’s going to allow us to calculate more
    complex forces in an environment that involves angles, such as a pendulum
    swinging or a box sliding down an incline.
  </p>

  <p>
    So this chapter is a bit of a mishmash. We’ll start with the basics of
    angles in p5 and cover many trigonometric topics, tying it all into
    forces at the end. And by taking this break now, we’ll also pave the way for
    more advanced examples that require trig later in this book.
  </p>

  <section data-type="sect1" id="chapter03_section1">
    <h2>3.1 Angles</h2>

    <a data-primary="angles" data-type="indexterm"></a>

    <p>
      OK. Before we can do any of this stuff, we need to make sure we understand
      what it means to be an angle in p5. If you have experience with
      p5, you’ve undoubtedly encountered this issue while using the
      <code>rotate()</code> function to rotate and spin objects.
    </p>

    <a
      data-primary="angles"
      data-secondary="measuring in degrees"
      data-type="indexterm"
    ></a>
    <a data-primary="degrees" data-type="indexterm"></a>

    <p>
      The first order of business is to cover
      <strong><em>radians</em></strong> and <strong><em>degrees</em></strong
      >. You’re probably familiar with the concept of an angle in
      <strong><em>degrees</em></strong
      >. A full rotation goes from 0 to 360 degrees. 90 degrees (a right angle)
      is 1/4th of 360, shown below as two perpendicular lines.
    </p>

    <figure id="chapter03_figure1">
      <img alt="Figure 3.1" src="chapter03/ch03_01.png" />
      <figcaption>Figure 3.1</figcaption>
    </figure>

    <p>
      It’s fairly intuitive for us to think of angles in terms of degrees. For
      example, the square in Figure 3.2 is rotated 45 degrees around its center.
    </p>

    <figure id="chapter03_figure2">
      <img alt="Figure 3.2" src="chapter03/ch03_02.png" />
      <figcaption>Figure 3.2</figcaption>
    </figure>

    <a
      data-primary="angles"
      data-secondary="measuring in radians"
      data-type="indexterm"
    ></a>
    <a
      data-primary="Processing"
      data-secondary="angles"
      data-tertiary="measuring in"
      data-type="indexterm"
    ></a>
    <a data-primary="radians" data-type="indexterm"></a>

    <p>
      p5, however, requires angles to be specified in
      <strong><em>radians</em></strong
      >. A radian is a unit of measurement for angles defined by the ratio of
      the length of the arc of a circle to the radius of that circle. One radian
      is the angle at which that ratio equals one (see Figure 3.3). 180 degrees
      = PI radians, 360 degrees = 2*PI radians, 90 degrees = PI/2 radians, etc.
    </p>

    <figure id="chapter03_figure3">
      <img alt="Figure 3.3" src="chapter03/ch03_03.png" />
      <figcaption>Figure 3.3</figcaption>
    </figure>

    <a
      data-primary="degrees"
      data-secondary="radians"
      data-tertiary="converting to"
      data-type="indexterm"
    ></a>
    <a
      data-primary="radians"
      data-secondary="converting from degrees"
      data-type="indexterm"
    ></a>

    <p>The formula to convert from degrees to radians is:</p>

    <p>radians = 2 * PI * (degrees / 360)</p>

    <a
      data-primary="Processing"
      data-secondary="radians() function"
      data-type="indexterm"
    ></a>
    <a data-primary="radians() function (Processing)" data-type="indexterm"></a>

    <p>
      Thankfully, if we prefer to think in degrees but code with radians,
      p5 makes this easy. The <code>radians()</code> function will
      automatically convert values from degrees to radians, and the constants
      <code>PI</code> and <code>TWO_PI</code> provide convenient access to these
      commonly used numbers (equivalent to 180 and 360 degrees, respectively).
      The following code, for example, will rotate shapes by 60 degrees.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
float angle = radians(60);
rotate(angle);</pre
    >

    <a
      data-primary="Processing"
      data-secondary="rotation tutorial"
      data-type="indexterm"
    ></a>

    <!-- TODO: add a new reference to 2D transforms in p5 -->
    <p>
      If you are not familiar with how rotation is implemented in p5, I
      would suggest this tutorial:
      <a href="http://www.processing.org/learning/transform2d/"
        >p5 — Transform 2D</a
      >.
    </p>

    <a data-primary="pi (π)" data-type="indexterm"></a>
    <a data-primary="PI variable (Processing)" data-type="indexterm"></a>

    <div data-type="note">
      <h2>What is PI?</h2>

      <p>
        The mathematical constant pi (or &pi;) is a real number defined as the
        ratio of a circle’s circumference (the distance around the perimeter) to
        its diameter (a straight line that passes through the circle’s center).
        It is equal to approximately 3.14159 and can be accessed in p5
        with the built-in variable <code>PI</code>.
      </p>
    </div>

    <div data-type="exercise" id="chapter03_exercise1">
      <h5>Exercise 3.1</h5>

      <p>
        Rotate a baton-like object (see below) around its center using
        <code>translate()</code> and <code>rotate()</code>.
      </p>

      <figure
        class="screenshot"
        data-p5-sketch="https://editor.p5js.org/embed/rk65mQXwX"
      >
        <img alt="ch03 exc01" src="chapter03/ch03_exc01.png" />
        <figcaption>&nbsp;</figcaption>
      </figure>
    </div>
  </section>

  <section data-type="sect1" id="chapter03_section2">
    <h2>3.2 Angular Motion</h2>

    <a
      data-primary="acceleration"
      data-secondary="rotation"
      data-type="indexterm"
    ></a>
    <a data-primary="angles" data-secondary="motion" data-type="indexterm"></a>
    <a data-primary="motion" data-secondary="angular" data-type="indexterm"></a>
    <a data-primary="rotation" data-type="indexterm"></a>
    <a
      data-primary="shapes"
      data-secondary="rotating"
      data-type="indexterm"
    ></a>

    <p>Remember all this stuff?</p>

    <p>
      <span class="formula">velocity = velocity + acceleration</span><br />
      <span class="formula">position = position + velocity</span>
    </p>

    <p>
      The stuff we dedicated almost all of Chapters 1 and 2 to? Well, we can
      apply exactly the same logic to a rotating object.
    </p>

    <p>
      <span class="formula"
        >angular velocity = angular velocity + angular acceleration</span
      ><br />
      <span class="formula">angle = angle + angular velocity</span>
    </p>

    <p>
      In fact, the above is actually simpler than what we started with because
      an angle is a <em>scalar</em> quantity—a single number, not a vector!
    </p>

    <p>
      Using the answer from Exercise 3.1 above, let’s say we wanted to rotate a
      baton in p5 by some angle. We would have code like:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
translate(width/2, height/2);
rotate(angle);
line(-50, 0, 50, 0);
ellipse(50, 0, 8, 8);
ellipse(-50, 0, 8, 8);</pre
    >

    <p>
      Adding in our principles of motion brings us to the following example.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/SJSSzlWOg"
    >
      <img alt="ch03 ex01" src="chapter03/ch03_ex01.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 3.1: Angular motion using rotate()</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
// position
let angle = 0;
// Velocity
let aVelocity = 0;
//{!1} Acceleration
let aAcceleration = 0.001;

function setup() {
  createCanvas(640, 360);
}

function draw() {
  background(255);

  fill(175);
  stroke(0);
  rectMode(CENTER);
  translate(width/2, height/2);
  rotate(angle);
  line(-50, 0, 50, 0);
  ellipse(50, 0, 8, 8);
  ellipse(-50, 0, 8, 8);

  // Angular equivalent of velocity.add(acceleration);
  aVelocity += aAcceleration;
  //{!1} Angular equivalent of position.add(velocity);
  angle += aVelocity;
}</pre
    >

    <p>
      The baton starts onscreen with no rotation and then spins faster and
      faster as the angle of rotation accelerates.
    </p>

    <p>
      This idea can be incorporated into our <code>Mover</code> object. For
      example, we can add the variables related to angular motion to our
      <code>Mover</code>.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Mover {

  constructor(){
    this.position = createVector();
    this.velocity = createVector();
    this.acceleration = createVector();
    this.mass = 1.0;

    this.angle = 0;
    this.aVelocity = 0;
    this.aAcceleration = 0;
  }  

}</pre
    >

    <p>
      And then in <code>update()</code>, we update both position and angle
      according to the same algorithm!
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
update() {
  //{!2} Regular old-fashioned motion
  this.velocity.add(this.acceleration);
  this.position.add(this.velocity);

  //{!2} Newfangled angular motion
  this.aVelocity += this.aAcceleration;
  this.angle += this.aVelocity;

  this.acceleration.mult(0);
}</pre
    >

    <p>
      Of course, for any of this to matter, we also would need to rotate the
      object when displaying it.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
display() {
  stroke(0);
  fill(175,200);
  rectMode(CENTER);
  //{!1} push() and pop() are necessary so that the rotation of this shape doesn’t affect the rest of our world.
  push();

  // Set the origin at the shape’s position.
  translate(this.position.x, this.position.y);
  //{!1} Rotate by the angle.
  rotate(this.angle);
  rect(0, 0, this.mass * 16, this.mass * 16);
  pop();
}</pre
    >

    <p>
      Now, if we were to actually go ahead and run the above code, we wouldn’t
      see anything new. This is because the angular acceleration (<code
        >this.aAcceleration = 0;</code
      >) is initialized to zero. For the object to rotate, we need to give it an
      acceleration! Certainly, we could hard-code in a different number.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
this.aAcceleration = 0.01;</pre
    >

    <p>
      However, we can produce a more interesting result by dynamically assigning
      an angular acceleration according to forces in the environment. Now, we
      could head far down this road, trying to model the physics of angular
      acceleration using the concepts of
      <a href="http://en.wikipedia.org/wiki/Torque">torque</a> and
      <a href="http://en.wikipedia.org/wiki/Moment_of_inertia"
        >moment of inertia</a
      >. Nevertheless, this level of simulation is beyond the scope of this
      book. (We will see more about modeling angular acceleration with a
      pendulum later in this chapter, as well as look at how Box2D realistically
      models rotational motion in Chapter 5.)
    </p>

    <p>
      For now, a quick and dirty solution will do. We can produce reasonable
      results by simply calculating angular acceleration as a function of the
      object’s acceleration vector. Here’s one such example:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
    this.aAcceleration = this.acceleration.x;</pre
    >

    <p>
      Yes, this is completely arbitrary. But it does do something. If the object
      is accelerating to the right, its angular rotation accelerates in a
      clockwise direction; acceleration to the left results in a
      counterclockwise rotation. Of course, it’s important to think about scale
      in this case. The <em>x</em> component of the acceleration vector might be
      a quantity that’s too large, causing the object to spin in a way that
      looks ridiculous or unrealistic. So dividing the <em>x</em> component by
      some value, or perhaps constraining the angular velocity to a reasonable
      range, could really help. Here’s the entire <code>update()</code> function
      with these tweaks added.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/r1W0zgWOg"
    >
      <img alt="ch03 ex02" src="chapter03/ch03_ex02.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 3.2: Forces with (arbitrary) angular motion</h5>
    </div>

    <pre data-code-language="java" data-type="programlisting" class="codesplit">
  update() {

    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);

    //{!1} Calculate angular acceleration according to acceleration’s horizontal direction and magnitude.
    this.aAcceleration = this.acceleration.x / 10.0;
    this.aVelocity += this.aAcceleration;
    //{!1} Use constrain() to ensure that angular velocity doesn’t spin out of control.
    this.aVelocity = constrain(this.aVelocity, -0.1, 0.1);
    this.angle += this.aVelocity;

    this.acceleration.mult(0);
  }</pre
    >

    <div data-type="exercise" id="chapter03_exercise2">
      <h5>Exercise 3.2</h5>

      <p>
        Step 1: Create a simulation where objects are shot out of a cannon. Each
        object should experience a sudden force when shot (just once) as well as
        gravity (always present).
      </p>

      <p>
        Step 2: Add rotation to the object to model its spin as it is shot from
        the cannon. How realistic can you make it look?
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter03_section3">
    <h2>3.3 Trigonometry</h2>

    <a data-primary="&lt;em&gt;sohcahtoa&lt;/em&gt;" data-type="indexterm"></a>
    <a data-primary="trigonometry" data-type="indexterm"></a>
    <a
      data-primary="trigonometry"
      data-secondary="&lt;em&gt;sohcahtoa&lt;/em&gt;"
      data-type="indexterm"
    ></a>

    <p>
      I think it may be time. We’ve looked at angles, we’ve spun an object. It’s
      time for: <em>sohcahtoa</em>. Yes, <em>sohcahtoa</em>. This seemingly
      nonsensical word is actually the foundation for a lot of computer graphics
      work. A basic understanding of trigonometry is essential if you want to
      calculate an angle, figure out the distance between points, work with
      circles, arcs, or lines. And <em>sohcahtoa</em> is a mnemonic device
      (albeit a somewhat absurd one) for what the trigonometric functions sine,
      cosine, and tangent mean.
    </p>

    <figure id="chapter03_figure4">
      <img alt="Figure 3.4" src="chapter03/ch03_04.png" />
      <figcaption>Figure 3.4</figcaption>
    </figure>

    <ul>
      <li>
        <p>
          <strong><em>soh</em></strong
          >: sine = opposite / hypotenuse
        </p>
      </li>
      <li>
        <p>
          <strong><em>cah</em></strong
          >: cosine = adjacent / hypotenuse
        </p>
      </li>
      <li>
        <p>
          <strong><em>toa</em></strong
          >: tangent = opposite / adjacent
        </p>
      </li>
    </ul>

    <figure class="half-width-right" id="chapter03_figure5">
      <img alt="Figure 3.5" src="chapter03/ch03_05.png" />
      <figcaption>Figure 3.5</figcaption>
    </figure>

    <p>
      Take a look at Figure 3.4 again. There’s no need to memorize it, but make
      sure you feel comfortable with it. Draw it again yourself. Now let’s draw
      it a slightly different way (Figure 3.5).
    </p>

    <a
      data-primary="vectors"
      data-secondary="as right triangles"
      data-type="indexterm"
    ></a>

    <p>
      See how we create a right triangle out of a vector? The vector arrow
      itself is the hypotenuse and the components of the vector (<code>x</code>
      and <code>y</code>) are the sides of the triangle. The angle is an
      additional means for specifying the vector’s direction (or “heading”).
    </p>

    <p>
      Because the trigonometric functions allow us to establish a relationship
      between the components of a vector and its direction + magnitude, they
      will prove very useful throughout this book. We’ll begin by looking at an
      example that requires the tangent function.
    </p>
  </section>

  <section data-type="sect1" id="chapter03_section4">
    <h2>3.4 Pointing in the Direction of Movement</h2>

    <a
      data-primary="rotation"
      data-secondary="pointing towards movement"
      data-type="indexterm"
    ></a>

    <p>
      Let’s go all the way back to Example 1.10, which features a
      <code>Mover</code> object accelerating towards the mouse.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/ryAIHLIPe"
    >
      <img alt="ch01 ex10" src="chapter01/ch01_ex10.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <p>
      You might notice that almost all of the shapes we’ve been drawing so far
      are circles. This is convenient for a number of reasons, one of which is
      that we don’t have to consider the question of rotation. Rotate a circle
      and, well, it looks exactly the same. However, there comes a time in all
      motion programmers’ lives when they want to draw something on the screen
      that points in the direction of movement. Perhaps you are drawing an ant,
      or a car, or a spaceship. And when we say "point in the direction of
      movement," what we are really saying is “rotate according to the velocity
      vector.” Velocity is a vector, with an <code>x</code> and a
      <code>y</code> component, but to rotate in p5 we need an angle, in
      radians. Let’s draw our trigonometry diagram one more time, with an
      object’s velocity vector (Figure 3.6).
    </p>

    <figure class="half-width-right" id="chapter03_figure6">
      <img alt="Figure 3.6" src="chapter03/ch03_06.png" />
      <figcaption>Figure 3.6</figcaption>
    </figure>

    <a data-primary="tangent" data-type="indexterm"></a>
    <a
      data-primary="trigonometry"
      data-secondary="tangent"
      data-type="indexterm"
    ></a>
    <a
      data-primary="vectors"
      data-secondary="tangent"
      data-type="indexterm"
    ></a>

    <p>OK. We know that the definition of tangent is:</p>

    <div class="equation-w-frac-big">
      <div data-type="equation">
        {tangent}({angle}) = \frac{velocity_x}{velocity_y}
      </div>
    </div>

    <p>
      The problem with the above is that we know velocity, but we don’t know the
      angle. We have to solve for the angle. This is where a special function
      known as <em>inverse tangent</em> comes in, sometimes referred to as
      <em>arctangent</em> or <em>tan<sup>-1</sup></em
      >. (There is also an <em>inverse sine</em> and an
      <em>inverse cosine</em>.)
    </p>

    <p>
      If the tangent of some value <code>a</code> equals some value
      <code>b</code>, then the inverse tangent of <code>b</code> equals
      <code>a</code>. For example:
    </p>

    <dl>
      <dt><em>if</em></dt>
      <dd>
        <p><em>tangent(a) = b</em></p>
      </dd>
      <dt><em>then</em></dt>
      <dd>
        <p><em>a = arctangent(b)</em></p>
      </dd>
    </dl>

    <p>
      See how that is the inverse? The above now allows us to solve for the
      angle:
    </p>

    <dl>
      <dt><em>if</em></dt>
      <dd>
        <p>
          <em>tangent(angle) = velocity<sub>y</sub> / velocity<sub>x</sub></em>
        </p>
      </dd>
      <dt><em>then</em></dt>
      <dd>
        <p>
          <em
            >angle = arctangent(velocity<sub>y</sub> / velocity<sub>x</sub>)</em
          >
        </p>
      </dd>
    </dl>

    <a data-primary="atan() function (Processing)" data-type="indexterm"></a>
    <a
      data-primary="Processing"
      data-secondary="atan() function"
      data-type="indexterm"
    ></a>
    <a
      data-primary="tangent"
      data-secondary="atan() function (arctangent)"
      data-type="indexterm"
    ></a>
    <a
      data-primary="trigonometry"
      data-secondary="atan() function"
      data-type="indexterm"
    ></a>

    <p>
      Now that we have the formula, let’s see where it should go in our mover’s
      <code>display()</code> function. Notice that in p5, the function
      for arctangent is called <code>atan()</code>.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  display() {
    //{!1} Solve for angle by using atan().
    this.angle = atan(this.velocity.y / this.velocity.x);

    stroke(0);
    fill(175);
    push();
    rectMode(CENTER);
    translate(this.position.x, this.position.y);
    //{!1} Rotate according to that angle.
    rotate(this.angle);
    rect(0, 0, 30, 10);
    pop();
  }</pre
    >

    <p>
      Now the above code is pretty darn close, and almost works. We still have a
      big problem, though. Let’s consider the two velocity vectors depicted
      below.
    </p>

    <figure id="chapter03_figure7">
      <img alt="Figure 3.7" src="chapter03/ch03_07.png" />
      <figcaption>Figure 3.7</figcaption>
    </figure>

    <p>
      Though superficially similar, the two vectors point in quite different
      directions—opposite directions, in fact! However, if we were to apply our
      formula to solve for the angle to each vector…
    </p>

    <p>
      <span class="formula"
        >V1 &rArr; angle = atan(3/-4) = atan(-0.75) = -0.6435011 radians = -37
        degrees</span
      ><br />
      <span class="formula"
        >V2 &rArr; angle = atan(-3/4) = atan(-0.75) = -0.6435011 radians = -37
        degrees</span
      >
    </p>

    <a data-primary="atan2() function (Processing)" data-type="indexterm"></a>
    <a
      data-primary="Processing"
      data-secondary="atan2() function"
      data-type="indexterm"
    ></a>
    <a
      data-primary="tangent"
      data-secondary="atan2() function"
      data-type="indexterm"
    ></a>

    <p>
      …we get the same angle for each vector. This can’t be right for both; the
      vectors point in opposite directions! The thing is, this is a pretty
      common problem in computer graphics. Rather than simply using
      <code>atan()</code> along with a bunch of conditional statements to
      account for positive/negative scenarios, p5 (along with pretty
      much all programming environments) has a nice function called
      <code>atan2()</code> that does it for you.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/BkfQ7g-_l"
    >
      <img alt="ch03 ex03" src="chapter03/ch03_ex03.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 3.3: Pointing in the direction of motion</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  display() {
    //{!1} Using atan2() to account for all possible directions
    this.angle = atan2(this.velocity.y, this.velocity.x);

    stroke(0);
    fill(175);
    push();
    rectMode(CENTER);
    translate(this.position.x, this.position.y);
    //{!1} Rotate according to that angle.
    rotate(this.angle);
    rect(0, 0, 30, 10);
    pop();
  }</pre
    >

    <a
      data-primary="heading() function (PVector class)"
      data-type="indexterm"
    ></a>
    <a
      data-primary="motion"
      data-secondary="heading() function (PVector class)"
      data-type="indexterm"
    ></a>
    <a
      data-primary="PVector class (Processing)"
      data-secondary="heading() function"
      data-type="indexterm"
    ></a>
    <a
      data-primary="tangent"
      data-secondary="heading() function (PVector class)"
      data-type="indexterm"
    ></a>

    <p>
      To simplify this even further, the <code>p5.Vector</code> class itself
      provides a function called <code>heading()</code>, which takes care of
      calling <code>atan2()</code> for you so you can get the 2D direction
      angle, in radians, for any p5 <code>p5.Vector</code>.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
    // The easiest way to do this!
    this.angle = this.velocity.heading();</pre
    >

    <div data-type="exercise" id="chapter03_exercise3">
      <h5>Exercise 3.3</h5>

      <p>
        Create a simulation of a vehicle that you can drive around the screen
        using the arrow keys: left arrow accelerates the car to the left, right
        to the right. The car should point in the direction in which it is
        currently moving.
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter03_section5">
    <h2>3.5 Polar vs. Cartesian Coordinates</h2>

    <a data-primary="Cartesian coordinates" data-type="indexterm"></a>
    <a data-primary="coordinate systems" data-type="indexterm"></a>
    <a
      data-primary="coordinate systems"
      data-secondary="Cartesian"
      data-type="indexterm"
    ></a>
    <a data-primary="Descartes" data-secondary="René" data-type="indexterm"></a>
    <a
      data-primary="shapes"
      data-secondary="displaying"
      data-type="indexterm"
    ></a>

    <p>
      Any time we display a shape in p5, we have to specify a pixel
      position, a set of <code>x</code> and <code>y</code> coordinates. These
      coordinates are known as <strong><em>Cartesian coordinates</em></strong
      >, named for René Descartes, the French mathematician who developed the
      ideas behind Cartesian space.
    </p>

    <a
      data-primary="coordinate systems"
      data-secondary="polar"
      data-type="indexterm"
    ></a>
    <a data-primary="polar coordinates" data-type="indexterm"></a>

    <p>
      Another useful coordinate system known as
      <strong><em>polar coordinates</em></strong> describes a point in space as
      an angle of rotation around the origin and a radius from the origin.
      Thinking about this in terms of a vector:
    </p>

    <p>
      Cartesian coordinate—the <em>x</em>,<em>y</em> components of a vector<br />
      Polar coordinate—the magnitude (length) and direction (angle) of a vector
    </p>

    <a
      data-primary="coordinate systems"
      data-secondary="Processing and"
      data-type="indexterm"
    ></a>
    <a
      data-primary="Processing"
      data-secondary="coordinate systems and"
      data-type="indexterm"
    ></a>

    <p>
      p5’s drawing functions, however, don’t understand polar
      coordinates. Whenever we want to display something in p5, we have
      to specify positions as <em>(x,y)</em> Cartesian coordinates. However,
      sometimes it is a great deal more convenient for us to think in polar
      coordinates when designing. Happily for us, with trigonometry we can
      convert back and forth between polar and Cartesian, which allows us to
      design with whatever coordinate system we have in mind but always draw
      with Cartesian coordinates.
    </p>

    <a data-primary="theta (θ)" data-type="indexterm"></a>
    <a
      data-primary="angles"
      data-secondary="theta (θ)"
      data-type="indexterm"
    ></a>

    <figure id="chapter03_figure8">
      <img
        alt="Figure 3.8: The Greek letter θ (theta) is often used to denote an angle.  Since a polar coordinate is conventionally referred to as (r, θ), we’ll use theta as a variable name when referring to an angle."
        src="chapter03/ch03_08.png"
      />
      <figcaption>
        Figure 3.8: The Greek letter θ (theta) is often used to denote an angle.
        Since a polar coordinate is conventionally referred to as (r, θ), we’ll
        use theta as a variable name when referring to an angle.&nbsp;
      </figcaption>
    </figure>

    <p>
      <span class="formula"
        >sine(theta) &nbsp;&nbsp;= y/r &nbsp;&nbsp;&rarr;&nbsp;&nbsp; y = r
        <code>*</code> sine(theta)</span
      ><br />
      <span class="formula"
        >cosine(theta) = x/r &nbsp;&nbsp;&rarr;&nbsp;&nbsp; x = r
        <code>*</code> cosine(theta)</span
      >
    </p>

    <a
      data-primary="Cartesian coordinates"
      data-secondary="polar coordinates"
      data-tertiary="converting from"
      data-type="indexterm"
    ></a>
    <a data-primary="cos() function (Processing)" data-type="indexterm"></a>
    <a
      data-primary="polar coordinates"
      data-secondary="Cartesian coordinates"
      data-tertiary="converting to"
      data-type="indexterm"
    ></a>
    <a data-primary="sin() function (Processing)" data-type="indexterm"></a>
    <a
      data-primary="trigonometry"
      data-secondary="cos() function (Processing)"
      data-type="indexterm"
    ></a>
    <a
      data-primary="trigonometry"
      data-secondary="sin() function (Processing)"
      data-type="indexterm"
    ></a>

    <p>
      For example, if <code>r</code> is 75 and <code>theta</code> is 45 degrees
      (or PI/4 radians), we can calculate <code>x</code> and <code>y</code> as
      below. The functions for sine and cosine in p5 are
      <code>sin()</code> and <code>cos()</code>, respectively. They each take
      one argument, an angle measured in radians.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const r = 75;
const theta = PI / 4;
// Converting from polar (r,theta) to Cartesian (x,y)
const x = r * cos(theta);
const y = r * sin(theta);</pre
    >

    <a
      data-primary="shapes"
      data-secondary="moving with polar coordinates"
      data-type="indexterm"
    ></a>

    <p>
      This type of conversion can be useful in certain applications. For
      example, to move a shape along a circular path using Cartesian coordinates
      is not so easy. With polar coordinates, on the other hand, it’s simple:
      increment the angle!
    </p>

    <p>
      Here’s how it is done with global variables <code>r</code> and
      <code>theta</code>.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/S1UL7gZue"
    >
      <img alt="ch03 ex04" src="chapter03/ch03_ex04.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example"><h5>Example 3.4: Polar to Cartesian</h5></div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const r = 75;
let theta = 0;

function setup() {
  createCanvas(640, 360);
  background(255);
}

function draw() {

  //{!2} Polar coordinates (r,theta) are converted to Cartesian (x,y) for use in the ellipse() function.
  const x = r * cos(theta);
  const y = r * sin(theta);

  noStroke();
  fill(0);
  ellipse(x + width/2, y + height/2, 16, 16);

  theta += 0.01;
}</pre
    >

    <div data-type="exercise" id="chapter03_exercise4">
      <h5>Exercise 3.4</h5>

      <p>
        Using Example 3.4 as a basis, draw a spiral path. Start in the center
        and move outwards. Note that this can be done by only changing one line
        of code and adding one line of code!
      </p>

      <figure>
        <img alt="ch03 exc04" src="chapter03/ch03_exc04.png" />
        <figcaption>&nbsp;</figcaption>
      </figure>
    </div>

    <div data-type="exercise" id="chapter03_exercise5">
      <h5>Exercise 3.5</h5>

      <p>
        Simulate the spaceship in the game Asteroids. In case you aren’t
        familiar with Asteroids, here is a brief description: A spaceship
        (represented as a triangle) floats in two dimensional space. The left
        arrow key turns the spaceship counterclockwise, the right arrow key,
        clockwise. The <em>z</em> key applies a “thrust” force in the direction
        the spaceship is pointing.
      </p>

      <figure
        class="screenshot"
        data-p5-sketch="https://editor.p5js.org/embed/rJ1eCXXw7"
      >
        <img alt="ch03 exc05" src="chapter03/ch03_exc05.png" />
        <figcaption>&nbsp;</figcaption>
      </figure>
    </div>
  </section>

  <section data-type="sect1" id="chapter03_section6">
    <h2>3.6 Oscillation Amplitude and Period</h2>

    <a data-primary="oscillation" data-type="indexterm"></a>

    <p>
      Are you amazed yet? We’ve seen some pretty great uses of tangent (for
      finding the angle of a vector) and sine and cosine (for converting from
      polar to Cartesian coordinates). We could stop right here and be
      satisfied. But we’re not going to. This is only the beginning. What sine
      and cosine can do for you goes beyond mathematical formulas and right
      triangles.
    </p>

    <p>
      Let’s take a look at a graph of the sine function, where
      <em>y = sine(x)</em>.
    </p>

    <figure id="chapter03_figure9">
      <img alt="Figure 3.9: y = sine(x)" src="chapter03/ch03_09.png" />
      <figcaption>Figure 3.9: y = sine(x)</figcaption>
    </figure>

    <p>
      You’ll notice that the output of the sine function is a smooth curve
      alternating between &minus;1 and 1. This type of a behavior is known as
      <strong><em>oscillation</em></strong
      >, a periodic movement between two points. Plucking a guitar string,
      swinging a pendulum, bouncing on a pogo stick—these are all examples of
      oscillating motion.
    </p>

    <a
      data-primary="oscillation"
      data-secondary="simulating with sine curves"
      data-type="indexterm"
    ></a>

    <p>
      And so we happily discover that we can simulate oscillation in a
      p5 sketch by assigning the output of the sine function to an
      object’s position. Note that this will follow the same methodology we
      applied to Perlin noise in the <a href="#intro_section6">Introduction</a>.
    </p>

    <p>
      Let’s begin with a really basic scenario. We want a circle to oscillate
      from the left side to the right side of a p5 window.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/BJTYQlWOe"
    >
      <img alt="ch03 ex05" src="chapter03/ch03_ex05.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <a
      data-primary="oscillation"
      data-secondary="simple harmonic motion"
      data-type="indexterm"
    ></a>
    <a data-primary="simple harmonic motion" data-type="indexterm"></a>

    <p>
      This is what is known as
      <strong><em>simple harmonic motion</em></strong> (or, to be fancier, “the
      periodic sinusoidal oscillation of an object”). It’s going to be a simple
      program to write, but before we get into the code, let’s familiarize
      ourselves with some of the terminology of oscillation (and waves).
    </p>

    <p>
      Simple harmonic motion can be expressed as any position (in our case, the
      <code>x</code> position) as a function of time, with the following two
      elements:
    </p>

    <a data-primary="amplitude" data-type="indexterm"></a>
    <a
      data-primary="oscillation"
      data-secondary="amplitude"
      data-type="indexterm"
    ></a>
    <a
      data-primary="oscillation"
      data-secondary="period"
      data-type="indexterm"
    ></a>
    <a data-primary="period" data-type="indexterm"></a>

    <ul>
      <li>
        <p>
          <strong><em>Amplitude</em></strong
          >: The distance from the center of motion to either extreme
        </p>
      </li>
      <li>
        <p>
          <strong><em>Period</em></strong
          >: The amount of time it takes for one complete cycle of motion
        </p>
      </li>
    </ul>

    <p>
      Looking at the graph of sine (Figure 3.9), we can see that the amplitude
      is 1 and the period is <code>TWO_PI</code>; the output of sine never rises
      above 1 or below -1; and every <code>TWO_PI</code> radians (or 360
      degrees) the wave pattern repeats.
    </p>

    <p>
      Now, in the p5 world we live in, what is amplitude and what is
      period? Amplitude can be measured rather easily in pixels. In the case of
      a window 200 pixels wide, we would oscillate from the center 100 pixels to
      the right and 100 pixels to the left. Therefore:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
// Our amplitude is measured in pixels.
const amplitude = 100;</pre
    >

    <a data-primary="millis() function (Processing)" data-type="indexterm"></a>
    <a
      data-primary="Processing"
      data-secondary="measuring time in"
      data-type="indexterm"
    ></a>
    <a
      data-primary="time"
      data-secondary="millis() function"
      data-tertiary="measuring with"
      data-type="indexterm"
    ></a>
    <a data-primary="period" data-type="indexterm"></a>

    <p>
      <em>Period</em> is the amount of time it takes for one cycle, but what is
      time in our p5 world? I mean, certainly we could say we want the
      circle to oscillate every three seconds. And we could track the
      milliseconds—using <code>millis()</code> —in p5 and come up with
      an elaborate algorithm for oscillating an object according to real-world
      time. But for us, real-world time doesn’t really matter. The real measure
      of time in p5 is in frames. The oscillating motion should repeat
      every 30 frames, or 50 frames, or 1000 frames, etc.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
// Period is measured in frames (the unit of time for animation).
const period = 120;</pre
    >

    <p>
      Once we have the amplitude and period, it’s time to write a formula to
      calculate x as a function of time, which we now know is the current frame
      count.
    </p>

    <pre data-code-language="java" data-type="programlisting" class="codesplit">
const x = amplitude * sin(TWO_PI * frameCount / period);</pre
    >

    <a
      data-primary="map() function (Processing)"
      data-secondary="oscillation and"
      data-type="indexterm"
    ></a>

    <p>
      Let’s dissect the formula a bit more and try to understand each component.
      The first is probably the easiest. Whatever comes out of the sine function
      we multiply by amplitude. We know that sine will oscillate between -1 and
      1. If we take that value and multiply it by amplitude then we’ll get the
      desired result: a value oscillating between -amplitude and amplitude.
      (Note: this is also a place where we could use p5’s
      <code>map()</code> function to map the output of sine to a custom range.)
    </p>

    <p>Now, let’s look at what is inside the sine function:</p>

    <p>
      <span class="formula">TWO_PI <code>*</code> frameCount / period</span>
    </p>

    <p>
      What’s going on here? Let’s start with what we know. We know that sine
      will repeat every 2*PI radians—i.e. it will start at 0 and repeat at 2*PI,
      4*PI, 6*PI, etc. If the period is 120, then we want the oscillating motion
      to repeat when the <code>frameCount</code> is at 120 frames, 240 frames,
      360 frames, etc. <code>frameCount</code> is really the only variable; it
      starts at 0 and counts upward. Let’s take a look at what the formula
      yields with those values.
    </p>

    <table>
      <thead>
        <tr>
          <th>frameCount</th>
          <th>frameCount / period</th>
          <th>TWO_PI * frameCount / period</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <p>0</p>
          </td>
          <td>
            <p>0</p>
          </td>
          <td>
            <p>0</p>
          </td>
        </tr>
        <tr>
          <td>
            <p>60</p>
          </td>
          <td>
            <p>0.5</p>
          </td>
          <td>
            <p>PI</p>
          </td>
        </tr>
        <tr>
          <td>
            <p>120</p>
          </td>
          <td>
            <p>1</p>
          </td>
          <td>
            <p>TWO_PI</p>
          </td>
        </tr>
        <tr>
          <td>
            <p>240</p>
          </td>
          <td>
            <p>2</p>
          </td>
          <td>
            <p>2 * TWO_PI (or 4* PI)</p>
          </td>
        </tr>
        <tr>
          <td>
            <p>etc.</p>
          </td>
          <td>&nbsp;</td>
          <td>&nbsp;</td>
        </tr>
      </tbody>
    </table>

    <p>
      <code>frameCount</code> divided by <code>period</code> tells us how many
      cycles we’ve completed—are we halfway through the first cycle? Have we
      completed two cycles? By multiplying that number by <code>TWO_PI</code>,
      we get the result we want, since <code>TWO_PI</code> is the number of
      radians required for one sine (or cosine) to complete one cycle.
    </p>

    <p>
      Wrapping this all up, here’s the p5 example that oscillates the
      <code>x</code> position of a circle with an amplitude of 100 pixels and a
      period of 120 frames.
    </p>

    <div data-type="example"><h5>Example 3.5: Simple Harmonic Motion</h5></div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
function setup() {
  createCanvas(640, 360);
}

function draw() {
  background(255);

  const period = 120;
  const amplitude = 100;
  //{!1 .offset} Calculating horizontal position according to the formula for simple harmonic motion
  const x = amplitude * sin(TWO_PI * frameCount / period);
  stroke(0);
  fill(175);
  translate(width/2, height/2);
  line(0, 0, x, 0);
  ellipse(x, 0, 20, 20);
}</pre
    >

    <a data-primary="frequency (of oscillations)" data-type="indexterm"></a>
    <a
      data-primary="oscillation"
      data-secondary="frequency of"
      data-type="indexterm"
    ></a>

    <p>
      It’s also worth mentioning the term <strong><em>frequency</em></strong
      >: the number of cycles per time unit. Frequency is equal to 1 divided by
      <code>period</code>. If the period is 120 frames, then only 1/120th of a
      cycle is completed in one frame, and so frequency = 1/120. In the above
      example, we simply chose to define the rate of oscillation in terms of
      period and therefore did not need a variable for frequency.
    </p>

    <div data-type="exercise" id="chapter03_exercise6">
      <h5>Exercise 3.6</h5>

      <p>
        Using the sine function, create a simulation of a weight (sometimes
        referred to as a “bob”) that hangs from a spring from the top of the
        window. Use the <code>map()</code> function to calculate the vertical
        position of the bob. Later in this chapter, we’ll see how to recreate
        this same simulation by modeling the forces of a spring according to
        Hooke’s law.
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter03_section7">
    <h2>3.7 Oscillation with Angular Velocity</h2>

    <a
      data-primary="angular velocity"
      data-secondary="oscillation with"
      data-type="indexterm"
    ></a>
    <a
      data-primary="oscillation"
      data-secondary="angular velocity and"
      data-type="indexterm"
    ></a>

    <p>
      An understanding of the concepts of oscillation, amplitude, and
      frequency/period is often required in the course of simulating real-world
      behaviors. However, there is a slightly easier way to rewrite the above
      example with the same result. Let’s take one more look at our oscillation
      formula:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const x = amplitude * sin(TWO_PI * frameCount / period);</pre
    >

    <p>And let’s rewrite it a slightly different way:</p>

    <pre data-code-language="java" data-type="programlisting" class="codesplit">
const x = amplitude * sin ( some value that increments slowly );</pre
    >

    <p>
      If we care about precisely defining the period of oscillation in terms of
      frames of animation, we might need the formula the way we first wrote it,
      but we can just as easily rewrite our example using the concept of angular
      velocity (and acceleration) from
      <a href="#chapter03_section2">section 3.2</a>. Assuming:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let angle = 0;
const aVelocity = 0.05;</pre
    >

    <p>in <code>draw()</code>, we can simply say:</p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
angle += aVelocity;
const x = amplitude * sin(angle);</pre
    >

    <p><code>angle</code> is our “some value that increments slowly.”</p>

    <div data-type="example">
      <h5>Example 3.6: Simple Harmonic Motion II</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let angle = 0;
const aVelocity = 0.05;

function setup() {
  createCanvas(640, 360);
}

function draw() {
  background(255);

  const amplitude = 100;
  const x = amplitude * sin(angle);
  //{!1} Using the concept of angular velocity to increment an angle variable
  angle += aVelocity;

  ellipseMode(CENTER);
  stroke(0);
  fill(175);
  translate(width/2, height/2);
  line(0, 0, x, 0);
  ellipse(x, 0, 20, 20);
}</pre
    >

    <p>
      Just because we’re not referencing it directly doesn’t mean that we’ve
      eliminated the concept of <code>period</code>. After all, the greater the
      angular velocity, the faster the circle will oscillate (therefore lowering
      the period). In fact, the number of times it takes to add up the angular
      velocity to get to <code>TWO_PI</code> is the period or:
    </p>

    <p><span class="formula">period = TWO_PI / angular velocity</span></p>

    <a
      data-primary="oscillation"
      data-secondary="on two axes"
      data-type="indexterm"
    ></a>

    <p>
      Let’s expand this example a bit more and create an
      <code>Oscillator</code> class. And let’s assume we want the oscillation to
      happen along both the x-axis (as above) and the y-axis. To do this, we’ll
      need two angles, two angular velocities, and two amplitudes (one for each
      axis). Another perfect opportunity for <code>p5.Vector</code>!
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/rJkWNeWOx"
    >
      <img alt="ch03 ex07" src="chapter03/ch03_ex07.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example"><h5>Example 3.7: Oscillator objects</h5></div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Oscillator  {

  constructor()  {
    //{!3} Using a p5.Vector to track two angles!
    this.angle = createVector();
    this.velocity = createVector(random(-0.05,0.05),random(-0.05,0.05));
    //{!1 .offset} Random velocities and amplitudes
    this.amplitude = createVector(random(width/2), random(height/2));
  }

  oscillate()  {
    this.angle.add(this.velocity);
  }

  display()  {
    // Oscillating on the x-axis
    const x = sin(this.angle.x) * this.amplitude.x;
    //{!1} Oscillating on the y-axis
    const y = sin(this.angle.y) * this.amplitude.y;

    push();
    translate(width/2, height/2);
    stroke(0);
    fill(175);
    // Drawing the Oscillator as a line connecting a circle
    line(0, 0, x, y);
    ellipse(x, y, 16, 16);
    pop();
  }
}</pre
    >

    <div data-type="exercise" id="chapter03_exercise7">
      <h5>Exercise 3.7</h5>

      <p>
        Try initializing each <code>Oscillator</code> object with velocities and
        amplitudes that are not random to create some sort of regular pattern.
        Can you make the oscillators appear to be the legs of an insect-like
        creature?
      </p>
    </div>

    <div data-type="exercise" id="chapter03_exercise8">
      <h5>Exercise 3.8</h5>

      <p>
        Incorporate angular acceleration into the
        <code>Oscillator</code> object.
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter03_section8">
    <h2>3.8 Waves</h2>

    <a
      data-primary="oscillation"
      data-secondary="waves"
      data-type="indexterm"
    ></a>
    <a data-primary="waves" data-type="indexterm"></a>

    <p>
      If you’re saying to yourself, “Um, this is all great and everything, but
      what I really want is to draw a wave onscreen,” well, then, the time has
      come. The thing is, we’re about 90% there. When we oscillate a single
      circle up and down according to the sine function, what we are doing is
      looking at a single point along the x-axis of a wave pattern. With a
      little panache and a <code>for</code> loop, we can place a whole bunch of
      these oscillating circles next to each other.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/Byt94lW_x"
    >
      <img alt="ch03 ex09" src="chapter03/ch03_ex09.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <p>
      This wavy pattern could be used in the design of the body or appendages of
      a creature, as well as to simulate a soft surface (such as water).
    </p>

    <a
      data-primary="period"
      data-secondary="defined in pixels rather than frames"
      data-type="indexterm"
    ></a>
    <a
      data-primary="waves"
      data-secondary="angular velocity"
      data-tertiary="defining with"
      data-type="indexterm"
    ></a>

    <p>
      Here, we’re going to encounter the same questions of amplitude (height of
      pattern) and period. Instead of period referring to time, however, since
      we’re looking at the full wave, we can talk about period as the width (in
      pixels) of a full wave cycle. And just as with simple oscillation, we have
      the option of computing the wave pattern according to a precise period or
      simply following the model of angular velocity.
    </p>

    <p>
      Let’s go with the simpler case, angular velocity. We know we need to start
      with an angle, an angular velocity, and an amplitude:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let angle = 0;
const angleVel = 0.2;
const amplitude = 100;</pre
    >

    <p>
      Then we’re going to loop through all of the <code>x</code> values where we
      want to draw a point of the wave. Let’s say every 24 pixels for now. In
      that loop, we’re going to want to do three things:
    </p>

    <ol>
      <li>
        <p>
          Calculate the y position according to amplitude and sine of the angle.
        </p>
      </li>
      <li>
        <p>Draw a circle at the <em>(x,y)</em> position.</p>
      </li>
      <li>
        <p>Increment the angle according to angular velocity.</p>
      </li>
    </ol>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  for (let x = 0; x <= width; x += 24) {
    // 1) Calculate the y position according to amplitude and sine of the angle.
    const y = amplitude * sin(angle);
    // 2) Draw a circle at the (x,y) position.
    ellipse(x, y + height/2, 48, 48);
    // 3) Increment the angle according to angular velocity.
    angle += angleVel;
  }</pre
    >

    <p>
      Let’s look at the results with different values for <code>angleVel</code>:
    </p>

    <figure
      class="three-col"
      data-p5-sketch="https://editor.p5js.org/embed/B1JE_HQDX"
    >
      <img alt="angleVel = 0.05" src="chapter03/ch03_ex09a.png" />
      <figcaption>angleVel = 0.05&nbsp;</figcaption>
    </figure>

    <figure
      class="three-col"
      data-p5-sketch="https://editor.p5js.org/embed/HkfDFLQDX"
    >
      <img alt="angleVel = 0.2" src="chapter03/ch03_ex09b.png" />
      <figcaption>angleVel = 0.2&nbsp;</figcaption>
    </figure>

    <figure
      class="three-col"
      data-p5-sketch="https://editor.p5js.org/embed/SkOFK8QDX"
    >
      <img alt="angleVel = 0.4" src="chapter03/ch03_ex09c.png" />
      <figcaption>angleVel = 0.4&nbsp;</figcaption>
    </figure>

    <p>
      Notice how, although we’re not precisely computing the period of the wave,
      the higher the angular velocity, the shorter the period. It’s also worth
      noting that as the period becomes shorter, it becomes more and more
      difficult to make out the wave itself as the distance between the
      individual points increases. One option we have is to use
      <code>beginShape()</code> and <code>endShape()</code> to connect the
      points with a line.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/SJjQNeZOl"
    >
      <img alt="ch03 ex08" src="chapter03/ch03_ex08.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example">
      <h5>Example 3.8: Static wave drawn as a continuous line</h5>
    </div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let angle = 0;
const angleVel = 0.2;
const amplitude = 100;

function setup(){
  createCanvas(400, 200);
  background(255);

  stroke(0);
  strokeWeight(2);
  noFill();

  beginShape();
  for (let x = 0; x <= width; x += 5) {
    // Here’s an example of using the map() function
    // instead.
    const y = map(sin(angle), -1, 1, 0, height);
    // With beginShape() and endShape(), you call
    // vertex() to set all the vertices of your shape.
    vertex(x, y);
    angle += angleVel;
  }
  endShape();
}</pre
    >

    <a
      data-primary="oscillation"
      data-secondary="varying"
      data-type="indexterm"
    ></a>
    <a data-primary="waves" data-secondary="varying" data-type="indexterm"></a>

    <p>
      You may have noticed that the above example is static. The wave never
      changes, never undulates. This additional step is a bit tricky. Your first
      instinct might be to say: “Hey, no problem, we’ll just let theta be a
      global variable and let it increment from one cycle through
      <code>draw()</code> to another.”
    </p>

    <p>
      While it’s a nice thought, it doesn’t work. If you look at the wave, the
      righthand edge doesn’t match the lefthand; where it ends in one cycle of
      <code>draw()</code> can’t be where it starts in the next. Instead, what we
      need to do is have a variable dedicated entirely to tracking what value of
      angle the wave should start with. This angle (which we’ll call
      <code>startAngle</code>) increments with its own angular velocity.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/Byt94lW_x"
    >
      <img alt="ch03 ex09" src="chapter03/ch03_ex09.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example"><h5>Example 3.9: The Wave</h5></div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let startAngle = 0;
const angleVel = 0.1;

function setup() {
  createCanvas(400, 200);
}

function draw() {
  background(255);

  //{!2} In order to move the wave, we start at a different theta value each frame.
  let angle = startAngle;
  startAngle += 0.02;

  for (let x = 0; x <= width; x += 24) {
    const y = map(sin(angle),-1,1,0,height);
    stroke(0);
    fill(0,50);
    ellipse(x,y,48,48);
    angle += angleVel;
  }
}</pre
    >

    <div data-type="exercise" id="chapter03_exercise9">
      <h5>Exercise 3.9</h5>

      <p>
        Try using the Perlin noise function instead of sine or cosine with the
        above example.
      </p>
    </div>

    <div data-type="exercise" id="chapter03_exercise10">
      <h5>Exercise 3.10</h5>

      <p>
        Encapsulate the above examples into a <code>Wave</code> class and create
        a sketch that displays two waves (with different amplitudes/periods) as
        in the screenshot below. Move beyond plain circles and lines and try
        visualizing the wave in a more creative way.
      </p>

      <figure data-p5-sketch="https://editor.p5js.org/embed/SJgaiUmvm">
        <img alt="ch03 exc10" src="chapter03/ch03_exc10.png" />
        <figcaption>&nbsp;</figcaption>
      </figure>
    </div>

    <div data-type="exercise" id="chapter03_exercise11">
      <h5>Exercise 3.11</h5>

      <p>
        More complex waves can be produced by the values of multiple waves
        together. Create a sketch that implements this, as in the screenshot
        below.
      </p>

      <figure data-p5-sketch="https://editor.p5js.org/embed/SyHvVgZOl">
        <img alt="ch03 exc11" src="chapter03/ch03_exc11.png" />
        <figcaption>&nbsp;</figcaption>
      </figure>
    </div>
  </section>

  <section data-type="sect1" id="chapter03_section9">
    <h2>3.9 Trigonometry and Forces: The Pendulum</h2>

    <a
      data-primary="forces"
      data-secondary="trigonometry and"
      data-type="indexterm"
    ></a>
    <a
      data-primary="natural phenomena"
      data-secondary="pivots"
      data-tertiary="modeling"
      data-type="indexterm"
    ></a>
    <a
      data-primary="pivots"
      data-secondary="modeling"
      data-type="indexterm"
    ></a>
    <a
      data-primary="trigonometry"
      data-secondary="forces and"
      data-type="indexterm"
    ></a>

    <p>
      Do you miss Newton’s laws of motion? I know I sure do. Well, lucky for
      you, it’s time to bring it all back home. After all, it’s been nice
      learning about triangles and tangents and waves, but really, the core of
      this book is about simulating the physics of moving bodies. Let’s take a
      look at how trigonometry can help us with this pursuit.
    </p>

    <figure class="two-col-borderless" id="chapter03_figure10">
      <img alt="Figure 3.10" src="chapter03/ch03_10.png" />
      <figcaption>Figure 3.10</figcaption>
    </figure>

    <figure class="two-col-borderless" id="chapter03_figure11">
      <img alt="Figure 3.11" src="chapter03/ch03_11.png" />
      <figcaption>Figure 3.11</figcaption>
    </figure>

    <p>
      A pendulum is a bob suspended from a pivot. Obviously a real-world
      pendulum would live in a 3D space, but we’re going to look at a simpler
      scenario, a pendulum in a 2D space—a p5 window (see Figure 3.10).
    </p>

    <a
      data-primary="acceleration"
      data-secondary="angular"
      data-tertiary="determining"
      data-type="indexterm"
    ></a>
    <a data-primary="angular acceleration" data-type="indexterm"></a>

    <p>
      In Chapter 2, we learned how a force (such as the force of gravity in
      Figure 3.11) causes an object to accelerate.
      <span class="mono">F = M <code>*</code> A</span> or
      <span class="mono">A = F / M</span>. In this case, however, the pendulum
      bob doesn’t simply fall to the ground because it is attached by an arm to
      the pivot point. And so, in order to determine its
      <em>angular</em> acceleration, we not only need to look at the force of
      gravity, but also the force at the angle of the pendulum’s arm (relative
      to a pendulum at rest with an angle of 0).
    </p>

    <p>
      In the above case, since the pendulum’s arm is of fixed length, the only
      variable in the scenario is the angle. We are going to simulate the
      pendulum’s motion through the use of angular velocity and acceleration.
      The angular acceleration will be calculated using Newton’s second law with
      a little trigonometry twist.
    </p>

    <p>Let’s zoom in on the right triangle from the pendulum diagram.</p>

    <figure class="half-width-right" id="chapter03_figure12">
      <img alt="Figure 3.12" src="chapter03/ch03_12.png" />
      <figcaption>Figure 3.12</figcaption>
    </figure>

    <a
      data-primary="gravity"
      data-secondary="modeling with trigonometry"
      data-type="indexterm"
    ></a>

    <p>
      We can see that the force of the pendulum (<code>F<sub>p</sub></code
      >) should point perpendicular to the arm of the pendulum in the direction
      that the pendulum is swinging. After all, if there were no arm, the bob
      would just fall straight down. It’s the tension force of the arm that
      keeps the bob accelerating towards the pendulum’s rest state. Since the
      force of gravity (<code>F<sub>g</sub></code
      >) points downward, by making a right triangle out of these two vectors,
      we’ve accomplished something quite magnificent. We’ve made the force of
      gravity the hypotenuse of a right triangle and separated the vector into
      two components, one of which represents the force of the pendulum. Since
      sine equals opposite over hypotenuse, we have:
    </p>

    <p>
      <span class="formula">sine(&theta;) = F<sub>p</sub> / F<sub>g</sub></span>
    </p>

    <p>Therefore:</p>

    <p>
      <span class="formula"
        >F<sub>p</sub> = F<sub>g</sub> <code>*</code> sine(&theta;)</span
      >
    </p>

    <p>
      Lest we forget, we’ve been doing all of this with a single question in
      mind: What is the angular acceleration of the pendulum? Once we have the
      angular acceleration, we’ll be able to apply our rules of motion to find
      the new angle for the pendulum.
    </p>

    <p>
      <span class="formula"
        >angular velocity = angular velocity + angular acceleration</span
      ><br />
      <span class="formula">angle = angle + angular velocity</span>
    </p>

    <p>
      The good news is that with Newton’s second law, we know that there is a
      relationship between force and acceleration, namely F = M * A, or A = F /
      M. So if the force of the pendulum is equal to the force of gravity times
      sine of the angle, then:
    </p>

    <p>
      <span class="formula"
        >pendulum angular acceleration = acceleration due to gravity
        <code>*</code> sine (&theta;)</span
      >
    </p>

    <a
      data-primary="gravity"
      data-secondary="modeling reality vs. arbitrary values"
      data-type="indexterm"
    ></a>
    <a
      data-primary="natural phenomena"
      data-secondary="modeling reality vs. arbitrary values"
      data-type="indexterm"
    ></a>

    <p>
      This is a good time to remind ourselves that we’re p5 programmers
      and not physicists. Yes, we know that the acceleration due to gravity on
      earth is 9.8 meters per second squared. But this number isn’t relevant to
      us. What we have here is just an arbitrary constant (we’ll call it
      <code>gravity</code>), one that we can use to scale the acceleration to
      something that feels right.
    </p>

    <p>
      <span class="formula"
        >angular acceleration = gravity <code>*</code> sine(&theta;)</span
      >
    </p>

    <p>
      Amazing. After all that, the formula is so simple. You might be wondering,
      why bother going through the derivation at all? I mean, learning is great
      and all, but we could have easily just said, "Hey, the angular
      acceleration of a pendulum is some constant times the sine of the angle."
      This is just another moment in which we remind ourselves that the purpose
      of the book is not to learn how pendulums swing or gravity works. The
      point is to think creatively about how things can move about the screen in
      a computationally based graphics system. The pendulum is just a case
      study. If you can understand the approach to programming a pendulum, then
      however you choose to design your onscreen world, you can apply the same
      techniques.
    </p>

    <p>
      Of course, we’re not finished yet. We may be happy with our simple,
      elegant formula, but we still have to apply it in code. This is most
      definitely a good time to practice our object-oriented programming skills
      and create a <code>Pendulum</code> class. Let’s think about all the
      properties we’ve encountered in our pendulum discussion that the class
      will need:
    </p>

    <ul>
      <li>
        <p>arm length</p>
      </li>
      <li>
        <p>angle</p>
      </li>
      <li>
        <p>angular velocity</p>
      </li>
      <li>
        <p>angular acceleration</p>
      </li>
    </ul>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Pendulum  {

  constructor(){
    // Length of arm
    this.r = ????;
    // Pendulum arm angle
    this.angle = ????;
    // Angular velocity
    this.aVelocity = ????;
    // Angular acceleration
    this.aAcceleration = ????;
  } </pre
    >

    <p>
      We’ll also need to write a function <code>update()</code> to update the
      pendulum’s angle according to our formula…
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  update() {
    // Arbitrary constant
    const gravity = 0.4;
    // Calculate acceleration according to our formula.
    this.aAcceleration = -1 * gravity * sin(this.angle);
    // Increment velocity.
    this.aVelocity += this.aAcceleration;
    //{!1} Increment angle.
    this.angle += this.aVelocity;
  }</pre
    >

    <figure class="half-width-right" id="chapter03_figure13">
      <img alt="Figure 3.13" src="chapter03/ch03_13.png" />
      <figcaption>Figure 3.13</figcaption>
    </figure>

    <p>
      ...as well as a function <code>display()</code> to draw the pendulum in
      the window. This begs the question: “Um, where do we draw the pendulum?”
      We know the angle and the arm length, but how do we know the
      <em>x,y</em> (Cartesian!) coordinates for both the pendulum’s pivot point
      (let’s call it origin) and bob position (let’s call it position)? This may
      be getting a little tiring, but the answer, yet again, is trigonometry.
    </p>

    <p>
      The origin is just something we make up, as is the arm length. Let’s say:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
this.origin = createVector(100,10);
this.r = 125;</pre
    >

    <p>
      We’ve got the current angle stored in our variable <code>angle</code>. So
      relative to the origin, the pendulum’s position is a polar coordinate:
      <em>(r,angle)</em>. And we need it to be Cartesian. Luckily for us, we
      just spent some time (section 3.5) deriving the formula for converting
      from polar to Cartesian. And so:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const position = createVector(r * sin(this.angle), r* cos(this.angle));</pre
    >

    <p>
      Note, however that <code>sin(angle)</code> is used for the x-value and
      <code>cos(angle)</code> for the y. This is the opposite of the formula we
      established in Chapter 3. The reason for this is that we are looking for
      the top angle of the right-triangle pointing down as depicted in Figure
      3.13.
    </p>

    <p>
      Since the position is relative to wherever the origin happens to be, we
      can just add origin to the position <code>p5.Vector</code>:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
this.position.add(this.origin);</pre
    >

    <p>
      And all that remains is the little matter of drawing a line and ellipse
      (you should be more creative, of course).
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
stroke(0);
fill(175);
line(this.origin.x, this.origin.y, this.position.x, this.position.y);
ellipse(this.position.x, this.position.y, 16, 16);</pre
    >

    <p>
      Before we put everything together, there’s one last little detail I
      neglected to mention. Let’s think about the pendulum arm for a moment. Is
      it a metal rod? A string? A rubber band? How is it attached to the pivot
      point? How long is it? What is its mass? Is it a windy day? There are a
      lot of questions that we could continue to ask that would affect the
      simulation. We’re living, of course, in a fantasy world, one where the
      pendulum’s arm is some idealized rod that never bends and the mass of the
      bob is concentrated in a single, infinitesimally small point.
      Nevertheless, even though we don’t want to worry ourselves with all of the
      questions, we should add one more variable to our calculation of angular
      acceleration. To keep things simple, in our derivation of the pendulum’s
      acceleration, we assumed that the length of the pendulum’s arm is 1. In
      fact, the length of the pendulum’s arm affects the acceleration greatly:
      the longer the arm, the slower the acceleration. To simulate a pendulum
      more accurately, we divide by that length, in this case <code>r</code>.
      For a more involved explanation, visit
      <a href="http://calculuslab.deltacollege.edu/ODE/7-A-2/7-A-2-h.html"
        >The Simple Pendulum website</a
      >.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
this.aAcceleration = (-1 * G * sin(this.angle)) / r;</pre
    >

    <a
      data-primary="acceleration"
      data-secondary="damping"
      data-type="indexterm"
    ></a>
    <a data-primary="damping" data-type="indexterm"></a>
    <a data-primary="forces" data-secondary="damping" data-type="indexterm"></a>
    <a
      data-primary="friction"
      data-secondary="damping"
      data-type="indexterm"
    ></a>

    <p>
      Finally, a real-world pendulum is going to experience some amount of
      friction (at the pivot point) and air resistance. With our code as is, the
      pendulum would swing forever, so to make it more realistic we can use a
      “damping” trick. I say <em>trick</em> because rather than model the
      resistance forces with some degree of accuracy (as we did in Chapter 2),
      we can achieve a similar result by simply reducing the angular velocity
      during each cycle. The following code reduces the velocity by 1% (or
      multiplies it by 99%) during each frame of animation:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
this.aVelocity *= 0.99;</pre
    >

    <p>
      Putting everything together, we have the following example (with the
      pendulum beginning at a 45-degree angle).
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/ByF7Hx-Ol"
    >
      <img alt="ch03 ex10" src="chapter03/ch03_ex10.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example"><h5>Example 3.10: Swinging pendulum</h5></div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let p;

function setup() {
  createCanvas(640, 360);
  //{!1} We make a new Pendulum object with an origin position and arm length.
  p = new Pendulum(createVector(width/2,10),125);
}

function draw() {
  background(255);
  p.go();
}</pre
    >
    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Pendulum  {
     
  constructor( origin_, r_) {
    //{!7} Many, many variables to keep track of the Pendulum’s various properties
    this.origin = origin_.copy(); // position of arm origin
    this.position = createVector(); // position of bob
    this.r = r_; // Length of arm
    this.angle = PI/4; // Pendulum arm angle
    this.aVelocity = 0.0; // Angle velocity
    this.aAcceleration = 0.0; // Angle acceleration
    this.damping = 0.995; // Arbitrary damping
  }

  go() {
    this.update();
    this.display();
  }

  update() {
    const gravity = 0.4;
    //{!1 .code-wide} Formula we worked out for angular acceleration
    this.aAcceleration = (-1 * gravity / this.r) * sin(this.angle);

    //{!2} Standard angular motion algorithm
    this.aVelocity += this.aAcceleration;
    this.angle += this.aVelocity;

    // Apply some damping.
    this.aVelocity *= this.damping;
  }

  display() {
    //{!1} Where is the bob relative to the origin? Polar to Cartesian coordinates will tell us!
    this.position.set(this.r * sin(this.angle), this.r * cos(this.angle));
    this.position.add(this.origin);

    stroke(0);
    //{!1 .code-wide} The arm
    line(this.origin.x, this.origin.y, this.position.x, this.position.y);
    fill(175);
    //{!1 .code-wide} The bob
    ellipse(this.position.x, this.position.y, 16, 16);
  }
}</pre
    >

    <p>
      <em
        >(Note that the version of the example posted on the website has
        additional code to allow the user to grab the pendulum and swing it with
        the mouse.)</em
      >
    </p>

    <div data-type="exercise" id="chapter03_exercise12">
      <h5>Exercise 3.12</h5>

      <p>
        String together a series of pendulums so that the endpoint of one is the
        origin point of another. Note that doing this may produce intriguing
        results but will be wildly inaccurate physically. Simulating an actual
        double pendulum involves sophisticated equations, which you can read
        about here:
        <a href="http://scienceworld.wolfram.com/physics/DoublePendulum.html"
          ><em class="hyperlink"
            >http://scienceworld.wolfram.com/physics/DoublePendulum.html</em
          ></a
        >.
      </p>
    </div>

    <div data-type="exercise" id="chapter03_exercise13">
      <h5>Exercise 3.13</h5>

      <figure class="half-width-right">
        <img alt="ch03 exc13" src="chapter03/ch03_exc13.png" />
        <figcaption>&nbsp;</figcaption>
      </figure>

      <p>
        Using trigonometry, what is the magnitude of the normal force in the
        illustration on the right (the force perpendicular to the incline on
        which the sled rests)? Note that, as indicated, the “normal” force is a
        component of the force of gravity.
      </p>

      <figure>
        <img alt="blank" src="blank.png" />
        <figcaption>&nbsp;</figcaption>
      </figure>
    </div>

    <div data-type="exercise" id="chapter03_exercise14">
      <h5>Exercise 3.14</h5>

      <p>
        Create an example that simulates a box sliding down the incline with
        friction. Note that the magnitude of the friction force is equal to the
        normal force.
      </p>
    </div>
  </section>

  <section data-type="sect1" id="chapter03_section10">
    <h2>3.10 Spring Forces</h2>

    <a data-primary="forces" data-secondary="springs" data-type="indexterm"></a>
    <a data-primary="springs" data-type="indexterm"></a>

    <p>
      In <a href="#chapter03_section6">section 3.6</a>, we looked at modeling
      simple harmonic motion by mapping the sine wave to a pixel range.
      <a href="#chapter03_exercise6">Exercise 3.6</a> asked you to use this
      technique to create a simulation of a bob hanging from a spring. While
      using the <code>sin()</code> function is a quick-and-dirty,
      one-line-of-code way of getting something up and running, it won’t do if
      what we really want is to have a bob hanging from a spring in a
      two-dimensional space that responds to other forces in the environment
      (wind, gravity, etc.) To accomplish a simulation like this (one that is
      identical to the pendulum example, only now the arm is a springy
      connection), we need to model the forces of a spring using
      <code>p5.Vector</code>.
    </p>

    <figure id="chapter03_figure14">
      <img alt="Figure 3.14" src="chapter03/ch03_14.png" />
      <figcaption>Figure 3.14</figcaption>
    </figure>

    <a
      data-primary="forces"
      data-secondary="Hooke's law"
      data-type="indexterm"
    ></a>
    <a data-primary="Hooke's law" data-type="indexterm"></a>
    <a data-primary="Hooke" data-secondary="Robert" data-type="indexterm"></a>
    <a
      data-primary="springs"
      data-secondary="Hooke's law"
      data-type="indexterm"
    ></a>

    <p>
      The force of a spring is calculated according to Hooke’s law, named for
      Robert Hooke, a British physicist who developed the formula in 1660. Hooke
      originally stated the law in Latin: "<em>Ut tensio, sic vis</em>," or “As
      the extension, so the force.” Let’s think of it this way:
    </p>

    <p>
      <span class="highlight"
        >The force of the spring is directly proportional to the extension of
        the spring.</span
      >
    </p>

    <figure class="half-width-right" id="chapter03_figure15">
      <img
        alt="Figure 3.15: x = current length - rest length"
        src="chapter03/ch03_15.png"
      />
      <figcaption>
        Figure 3.15: x = current length - rest length&nbsp;
      </figcaption>
    </figure>

    <p>
      In other words, if you pull on the bob a lot, the force will be strong; if
      you pull on the bob a little, the force will be weak. Mathematically, the
      law is stated as follows:
    </p>

    <a
      data-primary="Hooke's law"
      data-secondary="formula for expressing"
      data-type="indexterm"
    ></a>

    <p>
      <span class="formula">F<sub>spring</sub> = - k <code>*</code> x</span>
    </p>

    <ul>
      <li>
        <p>
          <code>k</code> is constant and its value will ultimately scale the
          force. Is the spring highly elastic or quite rigid?
        </p>
      </li>
      <li>
        <p>
          <code>x</code> refers to the displacement of the spring, i.e. the
          difference between the current length and the rest length. The rest
          length is defined as the length of the spring in a state of
          equilibrium.
        </p>
      </li>
    </ul>

    <p>
      Now remember, force is a vector, so we need to calculate both magnitude
      and direction. Let’s look at one more diagram of the spring and label all
      the givens we might have in a p5 sketch.
    </p>

    <figure id="chapter03_figure16">
      <img alt="Figure 3.16" src="chapter03/ch03_16.png" />
      <figcaption>Figure 3.16</figcaption>
    </figure>

    <p>
      Let’s establish the following three variables as shown in Figure 3.16.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const anchor = createVector();
const position = createVector();
const restLength = ????;</pre
    >

    <a
      data-primary="springs"
      data-secondary="magnitude of force"
      data-tertiary="determining"
      data-type="indexterm"
    ></a>

    <p>
      First, let’s use Hooke’s law to calculate the magnitude of the force. We
      need to know <code>k</code> and <code>x</code>. <code>k</code> is easy;
      it’s just a constant, so let’s make something up.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
const k = 0.1;</pre
    >

    <a
      data-primary="springs"
      data-secondary="rest length"
      data-type="indexterm"
    ></a>

    <p>
      <code>x</code> is perhaps a bit more difficult. We need to know the
      “difference between the current length and the rest length.” The rest
      length is defined as the variable <code>restLength</code>. What’s the
      current length? The distance between the anchor and the bob. And how can
      we calculate that distance? How about the magnitude of a vector that
      points from the anchor to the bob? (Note that this is exactly the same
      process we employed when calculating distance in Example 2.9:
      gravitational attraction.)
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
//{!1} A vector pointing from anchor to bob gives us the current length of the spring.
const dir = p5.Vector.sub(bob, anchor);
const currentLength = dir.mag();
const x = currentLength - restLength;</pre
    >

    <a
      data-primary="springs"
      data-secondary="direction of force"
      data-tertiary="determining"
      data-type="indexterm"
    ></a>

    <p>
      Now that we’ve sorted out the elements necessary for the magnitude of the
      force (-1 * <code>k</code> * <code>x</code>), we need to figure out the
      direction, a unit vector pointing in the direction of the force. The good
      news is that we already have this vector. Right? Just a moment ago we
      thought to ourselves: “How we can calculate that distance? How about the
      magnitude of a vector that points from the anchor to the bob?” Well, that
      is the direction of the force!
    </p>

    <figure id="chapter03_figure17">
      <img alt="Figure 3.17" src="chapter03/ch03_17.png" />
      <figcaption>Figure 3.17</figcaption>
    </figure>

    <p>
      In Figure 3.17, we can see that if we stretch the spring beyond its rest
      length, there should be a force pulling it back towards the anchor. And if
      it shrinks below its rest length, the force should push it away from the
      anchor. This reversal of direction is accounted for in the formula with
      the -1. And so all we need to do is normalize the <code>p5.Vector</code> we
      used for the distance calculation! Let’s take a look at the code and
      rename that <code>p5.Vector</code> variable as “force.”
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
//{!4} Magnitude of spring force according to Hooke’s law
const k = 0.1;
const force = p5.Vector.sub(bob, anchor);
const currentLength = force.mag();
const x = currentLength - restLength;

//{!1} Direction of spring force (unit vector)
force.normalize();

// Putting it together: direction and magnitude!
force.mult(-1 * k * x);</pre
    >

    <a
      data-primary="object-oriented programming"
      data-secondary="structures"
      data-tertiary="choosing between"
      data-type="indexterm"
    ></a>

    <p>
      Now that we have the algorithm worked out for computing the spring force
      vector, the question remains: what object-oriented programming structure
      should we use? This, again, is one of those situations in which there is
      no “correct” answer. There are several possibilities; which one we choose
      depends on the program’s goals and one’s own personal coding style. Still,
      since we’ve been working all along with a <code>Mover</code> class, let’s
      keep going with this same framework. Let’s think of our
      <code>Mover</code> class as the spring’s “bob.” The bob needs
      <code>position</code>, <code>velocity</code>, and
      <code>acceleration</code> vectors to move about the screen. Perfect—we’ve
      got that already! And perhaps the bob experiences a gravity force via the
      <code>applyForce()</code> function. Just one more step—we need to apply
      the spring force:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
let bob;

function setup() {
  bob = new Bob();
}

function draw()  {
  //{!1} Our Chapter 2 “make-up-a-gravity force”
  const gravity = createVector(0, 1);
  bob.applyForce(gravity);
  //{!2 .bold} We need to also calculate and apply a spring force!
  const springForce = _______________????
  bob.applyForce(spring);

  //{!2} Our standard update() and display() functions
  bob.update();
  bob.display();
}</pre
    >

    <figure id="chapter03_figure18">
      <img alt="Figure 3.18" src="chapter03/ch03_18.png" />
      <figcaption>Figure 3.18</figcaption>
    </figure>

    <p>
      One option would be to write out all of the spring force code in the main
      <code>draw()</code> loop. But thinking ahead to when you might have
      multiple bobs and multiple spring connections, it makes a good deal of
      sense to write an additional class, a <code>Spring</code> class. As shown
      in Figure 3.18, the <code>Bob</code> class keeps track of the movements of
      the bob; the <code>Spring</code> class keeps track of the spring’s anchor
      and its rest length and calculates the spring force on the bob.
    </p>

    <p>This allows us to write a lovely main program as follows:</p>

    <pre data-code-language="javascript data-type="programlisting" class="codesplit">
let bob;
//{!1 .bold} Adding a Spring object
let spring;

function setup() {
  bob = new Bob();
  spring = new Spring();
}

function draw()  {
  const gravity = createVector(0,1);
  bob.applyForce(gravity);

  //{!1 .bold} This new function in the Spring class will take care of computing the force of the spring on the bob.
  spring.connect(bob);

  bob.update();
  bob.display();
  spring.display();
}</pre
    >

    <p>
      You may notice here that this is quite similar to what we did in
      <a href="#chapter02_example6">Example 2.6</a> with an attractor. There, we
      said something like:
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  const force = attractor.attract(mover);
  mover.applyForce(force);</pre
    >

    <p>The analogous situation here with a spring would be:</p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  const force = spring.connect(bob);
  bob.applyForce(force);</pre
    >

    <p>Nevertheless, in this example all we said was:</p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  spring.connect(bob);</pre
    >

    <p>
      What gives? Why don’t we need to call <code>applyForce()</code> on the
      bob? The answer is, of course, that we do need to call
      <code>applyForce()</code> on the bob. Only instead of doing it in
      <code>draw()</code>, we’re just demonstrating that a perfectly reasonable
      (and sometimes preferable) alternative is to ask the
      <code>connect()</code> function to internally handle calling
      <code>applyForce()</code> on the bob.
    </p>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
  connect(b) {
    const force = some fancy calculations

    //{!1} The function connect() takes care of calling applyForce() and therefore doesn’t have to return a vector to the calling area.
    b.applyForce(force);
  }</pre
    >

    <p>
      Why do it one way with the <code>Attractor</code> class and another way
      with the <code>Spring</code> class? When we were first learning about
      forces, it was a bit clearer to show all the forces being applied in the
      main <code>draw()</code> loop, and hopefully this helped you learn about
      force accumulation. Now that we’re more comfortable with that, perhaps
      it’s simpler to embed some of the details inside the objects themselves.
    </p>

    <p>
      Let’s take a look at the rest of the elements in the
      <code>Spring</code> class.
    </p>

    <figure
      class="screenshot"
      data-p5-sketch="https://editor.p5js.org/embed/HkzFHeZdg"
    >
      <img alt="ch03 ex11" src="chapter03/ch03_ex11.png" />
      <figcaption>&nbsp;</figcaption>
    </figure>

    <div data-type="example"><h5>Example 3.11: A Spring connection</h5></div>

    <pre data-code-language="javascript" data-type="programlisting" class="codesplit">
class Spring {

  //{!1} The constructor initializes the anchor point and rest length.
  constructor( x_, y_, l_) {
    //{!1} We need to keep track of the spring’s anchor position.
    this.anchor = createVector(x_,y_);
    //{!2} Rest length and spring constant variables
    this.len = l_;
    this.k = 0.1;
  }

  //{!1} Calculate spring force—our implementation of Hooke’s Law.
  connect(b) {

    //{!1 .bold .code-wide} Get a vector pointing from anchor to Bob position.
    const force = p5.Vector.sub(b.position, this.anchor);
    //{!2 .bold} Calculate the displacement between distance and rest length.
    const d = force.mag();
    const stretch = d - this.len;

    //{!2 .bold} Direction and magnitude together!
    force.normalize();
    force.mult(-1 * this.k * stretch);

    //{!1} Call applyForce() right here!
    b.applyForce(force);
  }

  //{!5} Draw the anchor.
  display() {
    fill(100);
    rectMode(CENTER);
    rect(this.anchor.x,this.anchor.y,10,10);
  }

  //{!4} Draw the spring connection between Bob position and anchor.
  displayLine(b) {
    stroke(255);
    line(b.position.x,b.position.y,this.anchor.x,this.anchor.y);
  }
}</pre
    >

    <p>
      The full code for this example is included on the book website, and the
      Web version also incorporates two additional features: (1) the
      <code>Bob</code> class includes functions for mouse interactivity so that
      the bob can be dragged around the window, and (2) the
      <code>Spring</code> object includes a function to constrain the
      connection’s length between a minimum and a maximum.
    </p>

    <div data-type="exercise" id="chapter03_exercise15">
      <h5>Exercise 3.15</h5>

      <p>
        Before running to see the example online, take a look at this constrain
        function and see if you can fill in the blanks.
      </p>

      <pre
        data-code-language="javascript"
        data-type="programlisting"
        class="codesplit"
      >
constrainLength(b, minlen, maxlen) {
  //{!1} Vector pointing from Bob to Anchor
  const dir = p5.Vector.sub(______,______);
  const d = dir.mag();

  //{!1} Is it too short?
  if (d < minlen) {
    dir.normalize();
    dir.mult(________);
    //{!1} Keep position within constraint.
    b.position = p5.Vector.add(______,______);
    b.velocity.mult(0);
  //{!1} Is it too long?
  } else if (____________) {
    dir.normalize();
    dir.mult(_________);
    //{!1} Keep position within constraint.
    b.position = p5.Vector.add(______,______);
    b.velocity.mult(0);
  }
}</pre
      >
    </div>

    <div data-type="exercise" id="chapter03_exercise16">
      <h5>Exercise 3.16</h5>

      <p>
        Create a system of multiple bobs and spring connections. How would you
        have a bob connected to a bob with no fixed anchor?
      </p>
    </div>

    <div data-type="tip">
      <h2>The Ecosystem Project</h2>

      <p>Step 3 Exercise:</p>

      <p>
        Take one of your creatures and incorporate oscillation into its motion.
        You can use the <code>Oscillator</code> class from Example 3.7 as a
        model. The <code>Oscillator</code> object, however, oscillates around a
        single point (the middle of the window). Try oscillating around a moving
        point. In other words, design a creature that moves around the screen
        according to position, velocity, and acceleration. But that creature
        isn’t just a static shape, it’s an oscillating body. Consider tying the
        speed of oscillation to the speed of motion. Think of a butterfly’s
        flapping wings or the legs of an insect. Can you make it appear that the
        creature’s internal mechanics (oscillation) drive its locomotion? For a
        sample, check out the “AttractionArrayWithOscillation” example with the
        code download.
      </p>
    </div>
  </section>
</section>
